#include <unistd.h>
#include <signal.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>
int init_daemon(int argc, char* argv[], int(int, char*[]));
void watch_dog(int argc, char* argv[], int(*pMain)(int, char*[]))
{
    int pid = 0;

    do
    {
        pid = fork();

        if (pid > 0)
        {
            waitpid(-1, 0, 0);
        }
        else if (pid < 0)
        {
            break;
        }
        else
        {
            pMain(argc, argv);
            break;
        }
    }
    while (1);
}
int init_daemon(int argc, char* argv[], int(*pMain)(int, char*[]))
{
    int pid = 0;
    int i;

    if ((pid = fork()) > 0)
    {
        return -1;//是父进程，结束父进程
    }

    else if (pid < 0)
    {
        return -1;//fork失败，退出
    }

//是第一子进程，后台继续执行

    setsid();//第一子进程成为新的会话组长和进程组长
//并与控制终端分离
    if ((pid = fork()) > 0)
    {
        return -1;//是第一子进程，结束第一子进程
    }
    else if (pid < 0)
    {
        return -1;//fork失败，退出
    }

//是第二子进程，继续
//第二子进程不再是会话组长
    signal(SIGCHLD, SIG_IGN);

    for (i = 0; i < NOFILE; ++i) //关闭打开的文件描述符

    {
        close(i);
    }

    open("/dev/null", O_RDONLY);
    open("/dev/null", O_RDWR);
    open("/dev/null", O_RDWR);
    chdir("/");//改变工作目录到/tmp
    umask(0);//重设文件创建掩模
    watch_dog(argc, argv, pMain);
    return 0;
}

